package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.dto.LoginAuthDto;
import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.DmcCsunCameraLocationMapper;
import com.csun.cmny.provider.dao.DmcCsunGatewayLocationMapper;
import com.csun.cmny.provider.device.csun.camera.entity.CsunCameraData;
import com.csun.cmny.provider.device.csun.gateway.entity.CsunGatewayData;
import com.csun.cmny.provider.exceptions.DmcBizException;
import com.csun.cmny.provider.model.constant.DeviceConstant;
import com.csun.cmny.provider.model.domain.DmcCsunCameraLocation;
import com.csun.cmny.provider.model.domain.DmcCsunGatewayLocation;
import com.csun.cmny.provider.model.domain.DmcDevice;
import com.csun.cmny.provider.model.dto.camera.BindCsunCameraLocationDto;
import com.csun.cmny.provider.model.dto.camera.CsunCameraQueryDto;
import com.csun.cmny.provider.model.dto.gateway.BindCsunGatewayLocationDto;
import com.csun.cmny.provider.model.dto.gateway.CsunGatewayQueryDto;
import com.csun.cmny.provider.model.dto.gateway.GatewayBindDto;
import com.csun.cmny.provider.model.dto.propertyManagement.SelectDeviceDataDto;
import com.csun.cmny.provider.model.enums.device.DmcDeviceTypeEnum;
import com.csun.cmny.provider.model.vo.GatewayReqVo;
import com.csun.cmny.provider.model.vo.OldmanBedRoomBuildingVo;
import com.csun.cmny.provider.model.vo.RoomBuildingVo;
import com.csun.cmny.provider.model.vo.csuncamera.CsunCameraVo;
import com.csun.cmny.provider.model.vo.device.DmcDeviceVo;
import com.csun.cmny.provider.model.vo.gateway.DmcGatewayVo;
import com.csun.cmny.provider.model.vo.life.DmcDeviceByRoom;
import com.csun.cmny.provider.model.vo.propertyManagement.PropertyDataVo;
import com.csun.cmny.provider.resolver.CmnyMessageSource;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.util.PubUtils;
import com.csun.cmny.util.PublicUtil;
import com.csun.cmny.util.RedisKeyUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-09-02 14:15
 * @Description: the class dmc csun camera location service impl
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DmcCsunGatewayLocationServiceImpl extends BaseService<DmcCsunGatewayLocation>
        implements DmcCsunGatewayLocationService {
    @Resource
    private DmcDeviceService dmcDeviceService;
    @Resource
    private DmcCsunGatewayLocationMapper dmcCsunGatewayLocationMapper;
    @Resource
    private CmnyMessageSource cmnyMessageSource;
    @Resource
    private OmcRpcService omcRpcService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private DmcDeviceAlertService dmcDeviceAlertService;


    @Override
    public Integer bind(BindCsunGatewayLocationDto bindCsunGatewayLocationDto, LoginAuthDto loginAuthDto) {
        // 网关Id
        Long deviceId = bindCsunGatewayLocationDto.getDeviceId();
        // 绑定类型
        Integer bindType = bindCsunGatewayLocationDto.getBindType();
        // 绑定位置
        String location = bindCsunGatewayLocationDto.getLocation();
        // 老人姓名
        String oldmanName = bindCsunGatewayLocationDto.getOldmanName();
        // 老人Id
        Integer oldmanId = bindCsunGatewayLocationDto.getOldmanId();
        // 床位Id
        Integer bedId = bindCsunGatewayLocationDto.getBedId();
        // 房间Id
        Integer roomId = bindCsunGatewayLocationDto.getRoomId();

        //1,校验网关
        DmcDevice dmcDevice = dmcDeviceService.checkDeviceIsCsunGatewayByDeviceId(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100614004, deviceId);
        }
        //2,校验网关是否已经被绑定
        DmcCsunGatewayLocation dmcCsunGatewayLocation = dmcCsunGatewayLocationMapper.selectByPrimaryKey(deviceId);
        if(PublicUtil.isNotEmpty(dmcCsunGatewayLocation)){
            throw new DmcBizException(ErrorCodeEnum.DMC100616008, deviceId);
        }
        // 3、校验网关绑定类型
        Preconditions.checkArgument(!PubUtils.isNull(bindType),
                cmnyMessageSource.getMessage("csun.gateway.bind.type.null", null));

        Preconditions.checkArgument(bindType >= 0 && bindType <= 4,
                cmnyMessageSource.getMessage("csun.gateway.bind.type.range", null));

        switch (bindType) {  // 根据绑定类型不同进行校验
            case DeviceConstant.DEVICE_BIND_TYPE_CUSTOM :
                // 4、校验绑定位置
                Preconditions.checkArgument(!PubUtils.isNull(location),
                        cmnyMessageSource.getMessage("csun.gateway.bind.location.null", null));
                break;
            case DeviceConstant.DEVICE_BIND_TYPE_OLDMAN :
                Preconditions.checkArgument(!PubUtils.isNull(oldmanId),
                        cmnyMessageSource.getMessage("csun.gateway.bind.oldman.id.null", null));
                // 5、校验老人是否存在
                OldmanBedRoomBuildingVo oldmanBedRoomBuildingVo = omcRpcService
                        .queryOldmanBedRoomBuildingByOldmanId(oldmanId);
                if (PublicUtil.isEmpty(oldmanBedRoomBuildingVo)) {
                    // 老人不存在
                    throw new DmcBizException(ErrorCodeEnum.DMC100610062);
                }
                break;
            case DeviceConstant.DEVICE_BIND_TYPE_BED :
                // 6、校验床位是否存在
                Preconditions.checkArgument(!PubUtils.isNull(bedId),
                        cmnyMessageSource.getMessage("csun.gateway.bind.bed.id.null", null));
                // 校验房间Id是否存在
                OldmanBedRoomBuildingVo bedRoomBuildingVo = omcRpcService
                        .queryOldmanBedRoomBuildingByBedId(bedId);
                if (PublicUtil.isEmpty(bedRoomBuildingVo)) {
                    // 床位不存在
                    throw new DmcBizException(ErrorCodeEnum.DMC100610060);
                }
                break;
            // 7、校验房间是否绑定
            case DeviceConstant.DEVICE_BIND_TYPE_ROOM :
                Preconditions.checkArgument(!PubUtils.isNull(roomId),
                        cmnyMessageSource.getMessage("csun.gateway.bind.room.id.null", null));
                // 校验房间Id是否存在
                RoomBuildingVo roomBuildingVo = omcRpcService
                        .queryRoomBuildingByRoomId(roomId);
                if (PublicUtil.isEmpty(roomBuildingVo)) {
                    // 床位不存在
                    throw new DmcBizException(ErrorCodeEnum.DMC100610059);
                }
                break;
            case DeviceConstant.DEVICE_BIND_TYPE_LIFE :
                Preconditions.checkArgument(!PubUtils.isNull(roomId),
                        cmnyMessageSource.getMessage("csun.gateway.bind.room.id.null", null));
                // 校验房间Id是否存在

               /* *
                 * @date    2019-01-07
                 * @author  chisj
                 * @desc    一个房间只能绑定一个网关
                 */
                DmcCsunGatewayLocation dmcCsunGatewayLocation1 = new DmcCsunGatewayLocation();
                dmcCsunGatewayLocation1.setBindType(DeviceConstant.DEVICE_BIND_TYPE_LIFE);
                dmcCsunGatewayLocation1.setRoomId(bindCsunGatewayLocationDto.getRoomId());
                int count = dmcCsunGatewayLocationMapper.selectCount(dmcCsunGatewayLocation1);
                if (count > 0) {
                    throw new DmcBizException(ErrorCodeEnum.DMC100616009);
                }

                break;
        }
        //8,进行绑定
        DmcCsunGatewayLocation record = new DmcCsunGatewayLocation();
        BeanUtils.copyProperties(bindCsunGatewayLocationDto, record);
        record.setCreator(loginAuthDto.getUserName());
        record.setCreatorId(loginAuthDto.getUserId());
        int result = dmcCsunGatewayLocationMapper.insertSelective(record);


        // 9、缓存redis
        if (result > 0) {
            // 设置redisKey
            CsunGatewayData csunGatewayData = new CsunGatewayData();
            csunGatewayData.setDeviceId(dmcDevice.getId());
            csunGatewayData.setDeviceNo(dmcDevice.getDeviceNo());


            redisTemplate.opsForValue().set(RedisKeyUtil.getCsunGatewayKey(dmcDevice.getDeviceNo()),
                    csunGatewayData);
        } else {
            throw new DmcBizException(ErrorCodeEnum.DMC100610071);
        }

        return result;
    }

    @Override
    public Integer untied(Long deviceId) {
        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceService.checkDeviceIsCsunGatewayByDeviceId(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100614004, deviceId);
        }

        // 2.判断网关已经绑定
        DmcCsunGatewayLocation dmcCsunGatewayLocation = dmcCsunGatewayLocationMapper.selectByPrimaryKey(deviceId);
        if (PublicUtil.isEmpty(dmcCsunGatewayLocation)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100616010, deviceId);
        }

        // 3.解绑智能床垫-日创
        Integer result = dmcCsunGatewayLocationMapper.deleteByPrimaryKey(deviceId);
        if (result > 0) {
            if(dmcCsunGatewayLocation.getBindType().equals(DeviceConstant.DEVICE_BIND_TYPE_LIFE)){
                // 删除报警记录
                dmcDeviceAlertService.deleteByDeviceId(deviceId);
            }

          /*  // 删除设备绑定数据
            redisTemplate.delete(RedisKeyUtil.getCsunGatewayKey(dmcDevice.getDeviceNo()));*/
        }
        return result;
    }

    @Override
    public PageInfo queryDeviceListWithPage(CsunGatewayQueryDto csunGatewayQueryDto) {
        List<DmcGatewayVo> dmcGatewayVos = dmcCsunGatewayLocationMapper.queryDeviceListWithPage(csunGatewayQueryDto);

        return new PageInfo(dmcGatewayVos);
    }

    @Override
    public DmcDeviceByRoom selectRoomIdByDeviceId(Long alertId) {
        return dmcCsunGatewayLocationMapper.selectRoomIdByDeviceId(alertId);
    }

    @Override
    public List<PropertyDataVo> selectDeviceData(SelectDeviceDataDto selectDeviceDataDto) {
        return dmcCsunGatewayLocationMapper.selectDeviceData(selectDeviceDataDto);
    }

    /**
     * 根据房间Id查询网关
     *
     * @param roomIdList the room id list
     *
     * @return the gateway req vo
     */
    @Override
    public List<GatewayReqVo> queryGatewayByRoomIds(List<Integer> roomIdList) {

        return dmcCsunGatewayLocationMapper.queryGatewayByRoomIds(roomIdList);
    }
}
